import { EventsRes, IArcOfCircleParams } from '@amcax/base';
import { ctx2 } from '@app-cad/module';
import { addDimension } from '@app-cad/common/utils';
import {
  SKETCH_CENTEREVENTS,
  sketchEventCenter,
} from '@app-cad/environments/nextcad/events/SketchEventCenter';
import { Vector3 } from 'three-legacy';
import CmdBase from '../../CmdBase';
import { dimRender } from '../cmd-render-pick/render';
import { DimRadiusTool } from '../dimension/DimRadiusTool';
import { AnnotationType } from '../dimension/types';
import { MouseState, State } from './types';

export default class CmdInteractor extends CmdBase {
  drawState: MouseState = State.NONE;
  lineLength: number = 0;
  curveId: string = '';
  labelPosLV: Vector3 = null;
  dimRaduis: DimRadiusTool = null;
  radius: number = 0;
  center: Vector3 = null;
  point1: Vector3 = null;
  point2: Vector3 = null;
  isExist: boolean;

  constructor() {
    super();
    this.registerEvents();
    this.picker.clickNull();
  }

  reset() {
    this.drawState = State.NONE;
  }

  unregisterEvents() {
    sketchEventCenter()
      .off(SKETCH_CENTEREVENTS.POINTERUP, this.onMouseDown)
      .off(SKETCH_CENTEREVENTS.POINTERMOVE, this.onMouseMove)
      .off(SKETCH_CENTEREVENTS.KEYUP, this.onKeyUp)
      .setDefault();
  }

  registerEvents() {
    sketchEventCenter()
      .setState('dimRadius')
      .on(SKETCH_CENTEREVENTS.POINTERUP, this.onMouseDown)
      .on(SKETCH_CENTEREVENTS.POINTERMOVE, this.onMouseMove)
      .on(SKETCH_CENTEREVENTS.KEYUP, this.onKeyUp)
      .addExit(this.destroy.bind(this));
  }

  onMouseDown = ({ button }: EventsRes) => {
    if (button.onLeft) {
      if (this.drawState === State.NONE) {
        if (this.pickSnapInfo?.type === 'ArcOfCircle') {
          this.curveId = this.pickSnapInfo.id;
          const params = this.pickSnapInfo.params as IArcOfCircleParams;
          this.point1 = new Vector3(params.point1[0], params.point1[1], 0);
          this.point2 = new Vector3(params.point2[0], params.point2[1], 0);
          this.center = new Vector3(params.center[0], params.center[1], 0);
          this.radius = params.radius;
          this.addLine();
          this.drawState = State.DRAW;
          this.dimRaduis.labelFoucs();
        }
      }
    } else if (button.onRight && !this.closeRightClick) {
      this.drawState = State.NONE;
      this.reset();
      this.releaseObjects();
    }
  };
  onMouseMove = (e: EventsRes) => {
    this.setMouseWV(e, false, false);
    if (this.drawState === State.DRAW) {
      this.dimRaduis.update({
        labelPos: this.mouseWV,
      });
      ctx2.viewer.requestRender();
    }
  };
  addLine = () => {
    this.dimRaduis = new DimRadiusTool({
      dimConstraint: AnnotationType.RadiusAnno,
      curveIds: [this.curveId],
      center: this.center,
      point1: this.point1,
      point2: this.point2,
      radius: this.radius,
      faceCSys: this.faceCSys,
      labelPos: this.mouseWV,
      callback: (status) => {
        if (status === 'focus' && this.drawState === State.DRAW) {
          this.drawState = State.INPUT;
        } else if (this.drawState === State.INPUT && status === 'blur') {
          this.finishDraw();
          this.reset();
        }
      },
    });
    this.isExist = dimRender().isExistDim({
      objects: [this.curveId],
      type: 6,
    });
    if (this.isExist) {
      this.dimRaduis.setDisable();
    }
    this.dimRaduis.addTo(this.assisGroup);
    this.dimRaduis?.labelFoucs();
  };
  finishDraw = async () => {
    if (this.dimRaduis?.getVal() === 0) {
      this.releaseObjects();
      return;
    }
    addDimension(
      this.sketchId,
      {
        objects: [this.curveId],
        type: AnnotationType.RadiusAnno,
        value: this.dimRaduis.getVal(),
        points: this.dimRaduis.getPosLv(),
      },
      this.isExist,
    ).finally(() => {
      this.releaseObjects();
    });
  };

  releaseObjects() {
    this.assisGroup.clear();
    this.dimRaduis?.destroy();
    this.dimRaduis = null;
    ctx2.viewer.requestRender();
  }
}
